home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Marker.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  18.3 KB  |  834 lines

  1. /*
  2. **    Marker.c
  3. **
  4. **    Text block marker routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14.     /* BM_Draw():
  15.      *
  16.      *    Redraw or remove marked regions.
  17.      */
  18.  
  19. VOID
  20. BM_Draw(struct BlockMarker *Marker,VOID (*Select)(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height))
  21. {
  22.         /* Is the first line the same as the last line? If so,
  23.          * continue and mark only single characters. Else,
  24.          * determine first line and column to mark and last
  25.          * line and last column.
  26.          */
  27.  
  28.     if(Marker -> FirstLine != Marker -> LastLine)
  29.     {
  30.         LONG    First    = Marker -> FirstLine - Marker -> Top,
  31.             Last    = Marker -> LastLine  - Marker -> Top,
  32.             Lines;
  33.  
  34.             /* Is the first line visible? If so, mark it. */
  35.  
  36.         if(First >= 0)
  37.             (*Select)(Marker,Marker -> FirstColumn,First,Marker -> Width - Marker -> FirstColumn,1);
  38.         else
  39.         {
  40.             (*Select)(Marker,0,0,Marker -> Width,1);
  41.  
  42.             First = 0;
  43.         }
  44.  
  45.             /* Is the last line visible? If so, mark it. */
  46.  
  47.         if(Last >= 0 && Last < Marker -> Height)
  48.             (*Select)(Marker,0,Last,Marker -> LastColumn,1);
  49.         else
  50.             Last = Marker -> Height;
  51.  
  52.             /* Determine the number of lines the selection spans. */
  53.  
  54.         if((Lines = Last - First - 1) > 0)
  55.             (*Select)(Marker,0,First + 1,Marker -> Width,Lines);
  56.     }
  57.     else
  58.     {
  59.             /* Is the first column different from the last column? */
  60.  
  61.         if(Marker -> FirstColumn != Marker -> LastColumn)
  62.         {
  63.                 /* Is the line visible? If so, mark it. */
  64.  
  65.             if(Marker -> Top <= Marker -> LastLine && Marker -> LastLine < Marker -> Top + Marker -> Height)
  66.                 (*Select)(Marker,Marker -> FirstColumn,Marker -> FirstLine - Marker -> Top,Marker -> LastColumn - Marker -> FirstColumn,1);
  67.         }
  68.     }
  69. }
  70.  
  71.     /* BM_ClearMark(struct BlockMarker *Marker):
  72.      *
  73.      *    Free block marker memory.
  74.      */
  75.  
  76. VOID
  77. BM_ClearMark(struct BlockMarker *Marker)
  78. {
  79.     BM_Draw(Marker,Marker -> Unselect);
  80.  
  81.     FreeVecPooled(Marker);
  82. }
  83.  
  84.     /* BM_SetMark():
  85.      *
  86.      *    Create block marker structure.
  87.      */
  88.  
  89. struct BlockMarker *
  90. BM_SetMark(APTR Object,VPTR Select,VPTR Unselect,LONG Width,LONG Height,LONG LeftEdge,LONG TopEdge,LONG Top,LONG Lines,LONG X,LONG Y,LONG TextFontWidth,LONG TextFontHeight)
  91. {
  92.     if(Height && Lines)
  93.     {
  94.         struct BlockMarker *Marker;
  95.  
  96.             /* Allocate marker buffer. */
  97.  
  98.         if(Marker = (struct BlockMarker *)AllocVecPooled(sizeof(struct BlockMarker),MEMF_ANY | MEMF_CLEAR))
  99.         {
  100.                 /* Fill in the object or canvas, usually a RastPort. */
  101.  
  102.             Marker -> Object    = Object;
  103.  
  104.                 /* Fill in the canvas left and top edge. */
  105.  
  106.             Marker -> LeftEdge    = LeftEdge;
  107.             Marker -> TopEdge    = TopEdge;
  108.  
  109.                 /* Fill in the select and unselect routines. */
  110.  
  111.             Marker -> Select    = Select;
  112.             Marker -> Unselect    = Unselect;
  113.  
  114.                 /* Fill in current display window top and number of
  115.                  * lines in the buffer.
  116.                  */
  117.  
  118.             Marker -> Top        = Top;
  119.             Marker -> Lines        = Lines;
  120.  
  121.                 /* Fill in width and height of the display window. */
  122.  
  123.             Marker -> Width        = Width;
  124.             Marker -> Height    = Height;
  125.  
  126.                 /* Fill in the marker anchor point. */
  127.  
  128.             Marker -> FirstColumn    = X;
  129.             Marker -> LastColumn    = X;
  130.             Marker -> FirstLine    = Y + Top;
  131.             Marker -> LastLine    = Y + Top;
  132.  
  133.                 /* Fill in current mouse position. */
  134.  
  135.             Marker -> LastX        = X;
  136.             Marker -> LastY        = Y;
  137.  
  138.             Marker -> OriginX    = X;
  139.             Marker -> OriginY    = Y + Top;
  140.  
  141.                 /* Remember text font dimensions. */
  142.  
  143.             Marker -> TextFontWidth    = TextFontWidth;
  144.             Marker -> TextFontHeight= TextFontHeight;
  145.  
  146.             Marker -> WriteMask    = ((struct RastPort *)Object) -> Mask;
  147.         }
  148.  
  149.             /* Return marker buffer. */
  150.  
  151.         return(Marker);
  152.     }
  153.     else
  154.         return(NULL);
  155. }
  156.  
  157.     /* BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta):
  158.      *
  159.      *    Extend current block marker. This routine was
  160.      *    first written by me, but Martin Berndt rewrote it
  161.      *    after we both realised that it would not work
  162.      *    properly.
  163.      */
  164.  
  165. VOID
  166. BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta)
  167. {
  168.     if(Marker -> LastX != X || Marker -> LastY != Y)
  169.     {
  170.         LONG    OldCharPos,NewCharPos,
  171.             CharStart,CharEnd,
  172.             CharOrigin,
  173.             OriginY,
  174.             Lines;
  175.         BOOL    Crossed;
  176.  
  177.         OriginY = Marker -> OriginY - Marker -> Top;
  178.  
  179.             /* Deal with illegal X position. */
  180.  
  181.         if(X < 0)
  182.             X = 0;
  183.  
  184.         if(X > Marker -> Width)
  185.             X = Marker -> Width;
  186.  
  187.             /* Deal with illegal Y position. */
  188.  
  189.         if(Y < 0)
  190.             Y = 0;
  191.  
  192.         if(Y >= Marker -> Height)
  193.             Y = Marker -> Height - 1;
  194.  
  195.         if(Y + Marker -> Top >= Marker -> Lines)
  196.             Y = Marker -> Lines - Marker -> Top - 1;
  197.  
  198.             /* Is the Y position larger than the last line? If so,
  199.              * truncate it.
  200.              */
  201.  
  202.         if(Y > Marker -> Lines - Marker -> Top)
  203.             Y -= Marker -> Lines - Marker -> Top;
  204.  
  205.             /* Select the text. */
  206.  
  207.         OldCharPos    = (Marker -> LastY + Marker -> Top) * Marker -> Width + Marker -> LastX;
  208.         NewCharPos    = (Y + Marker -> Top) * Marker -> Width + X;
  209.  
  210.         CharStart    = Marker -> FirstLine * Marker -> Width + Marker -> FirstColumn;
  211.         CharEnd        = Marker -> LastLine * Marker -> Width + Marker -> LastColumn;
  212.  
  213.         CharOrigin    = Marker -> OriginY * Marker -> Width + Marker -> OriginX;
  214.  
  215.         Crossed        = (OldCharPos < CharOrigin) ^ (NewCharPos < CharOrigin);
  216.  
  217.         if(NewCharPos > OldCharPos)
  218.         {
  219.             if(Delta && Y < OriginY)
  220.                 (*Marker -> Select)(Marker,0,Y,Marker -> Width,1);
  221.  
  222.             if(Crossed)
  223.             {
  224.                 if((Lines = OriginY - Marker -> LastY - 1) >= 0)
  225.                 {
  226.                     (*Marker -> Unselect)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  227.  
  228.                     if(Lines > 0)
  229.                         (*Marker -> Unselect)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  230.  
  231.                     if(Marker -> OriginX)
  232.                         (*Marker -> Unselect)(Marker,0,OriginY,Marker -> OriginX,1);
  233.                 }
  234.                 else
  235.                 {
  236.                     if(Delta)
  237.                         (*Marker -> Unselect)(Marker,0,OriginY,Marker -> LastX,1);
  238.                     else
  239.                         (*Marker -> Unselect)(Marker,Marker -> LastX,OriginY,Marker -> OriginX - Marker -> LastX,1);
  240.                 }
  241.  
  242.                 Marker -> FirstColumn    = Marker -> OriginX;
  243.                 Marker -> FirstLine     = Marker -> OriginY;
  244.  
  245.                 Marker -> LastX        = Marker -> OriginX;
  246.                 Marker -> LastY        = OriginY;
  247.             }
  248.             else
  249.             {
  250.                 if(OldCharPos < CharOrigin)
  251.                 {
  252.                     if((Lines = Y - Marker -> LastY - 1) >= 0)
  253.                     {
  254.                         (*Marker -> Unselect)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  255.  
  256.                         if(Lines > 0)
  257.                             (*Marker -> Unselect)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  258.  
  259.                         (*Marker -> Unselect)(Marker,0,Y,X,1);
  260.                     }
  261.                     else
  262.                     {
  263.                         if(Delta)
  264.                             (*Marker -> Unselect)(Marker,0,Y,X,1);
  265.                         else
  266.                             (*Marker -> Unselect)(Marker,Marker -> LastX,Y,X - Marker -> LastX,1);
  267.                     }
  268.  
  269.                     Marker -> FirstColumn    = X;
  270.                     Marker -> FirstLine    = Y + Marker -> Top;
  271.                 }
  272.             }
  273.  
  274.             if(NewCharPos > CharEnd)
  275.             {
  276.                 if((Lines = Y - Marker -> LastY - 1) >= 0)
  277.                 {
  278.                     (*Marker -> Select)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  279.  
  280.                     if(Lines > 0)
  281.                         (*Marker -> Select)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  282.  
  283.                     (*Marker -> Select)(Marker,0,Y,X,1);
  284.                 }
  285.                 else
  286.                 {
  287.                     if(Delta)
  288.                         (*Marker -> Select)(Marker,0,Y,X,1);
  289.                     else
  290.                         (*Marker -> Select)(Marker,Marker -> LastX,Y,X - Marker -> LastX,1);
  291.                 }
  292.  
  293.                 Marker -> LastColumn    = X;
  294.                 Marker -> LastLine    = Y + Marker -> Top;
  295.             }
  296.         }
  297.         else
  298.         {
  299.             if(Delta && Y > OriginY)
  300.                 (*Marker -> Select)(Marker,0,Y,Marker -> Width,1);
  301.  
  302.             if(Crossed)
  303.             {
  304.                 if((Lines = Marker -> LastY - OriginY - 1) >= 0)
  305.                 {
  306.                     (*Marker -> Unselect)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  307.  
  308.                     if(Lines > 0)
  309.                         (*Marker -> Unselect)(Marker,0,OriginY + 1,Marker -> Width,Lines);
  310.  
  311.                     (*Marker -> Unselect)(Marker,Marker -> OriginX,OriginY,Marker -> Width - Marker -> OriginX,1);
  312.                 }
  313.                 else
  314.                 {
  315.                     if(Delta)
  316.                         (*Marker -> Unselect)(Marker,Marker -> LastX,OriginY,Marker -> Width - Marker -> LastX,1);
  317.                     else
  318.                         (*Marker -> Unselect)(Marker,Marker -> OriginX,OriginY,Marker -> LastX - Marker -> OriginX,1);
  319.                 }
  320.  
  321.                 Marker -> LastColumn    = Marker -> OriginX;
  322.                 Marker -> LastLine    = Marker -> OriginY;
  323.  
  324.                 Marker -> LastX        = Marker -> OriginX;
  325.                 Marker -> LastY        = OriginY;
  326.             }
  327.             else
  328.             {
  329.                 if(OldCharPos > CharOrigin)
  330.                 {
  331.                     if((Lines = Marker -> LastY - Y - 1) >= 0)
  332.                     {
  333.                         if(Marker -> LastX)
  334.                             (*Marker -> Unselect)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  335.  
  336.                         if(Lines > 0)
  337.                             (*Marker -> Unselect)(Marker,0,Y + 1,Marker -> Width,Lines);
  338.  
  339.                         (*Marker -> Unselect)(Marker,X,Y,Marker -> Width - X,1);
  340.                     }
  341.                     else
  342.                     {
  343.                         if(Delta)
  344.                             (*Marker -> Unselect)(Marker,X,Y,Marker -> Width - X,1);
  345.                         else
  346.                             (*Marker -> Unselect)(Marker,X,Y,Marker -> LastX - X,1);
  347.                     }
  348.  
  349.                     Marker -> LastColumn    = X;
  350.                     Marker -> LastLine    = Y + Marker -> Top;
  351.                 }
  352.             }
  353.  
  354.             if(NewCharPos < CharStart)
  355.             {
  356.                 if((Lines = Marker -> LastY - Y - 1) >= 0)
  357.                 {
  358.                     if(Marker -> LastX)
  359.                         (*Marker -> Select)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  360.  
  361.                     if(Lines > 0)
  362.                         (*Marker -> Select)(Marker,0,Y + 1,Marker -> Width,Lines);
  363.  
  364.                     (*Marker -> Select)(Marker,X,Y,Marker -> Width - X,1);
  365.                 }
  366.                 else
  367.                 {
  368.                     if(Delta)
  369.                         (*Marker -> Select)(Marker,X,Y,Marker -> Width - X,1);
  370.                     else
  371.                         (*Marker -> Select)(Marker,X,Y,Marker -> LastX - X,1);
  372.                 }
  373.  
  374.                 Marker -> FirstColumn    = X;
  375.                 Marker -> FirstLine    = Y + Marker -> Top;
  376.             }
  377.         }
  378.  
  379.         Marker -> LastX = X;
  380.         Marker -> LastY = Y;
  381.     }
  382. }
  383.  
  384.  
  385.     /* ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height):
  386.      *
  387.      *    Toggle selection subroutine.
  388.      */
  389.  
  390. VOID
  391. ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height)
  392. {
  393.     struct RastPort *RPort = (struct RastPort *)Marker -> Object;
  394.  
  395.     if(Width && Height)
  396.     {
  397.         ULONG    OldAPen    = ReadAPen(RPort),
  398.             OldBPen    = ReadBPen(RPort),
  399.             OldDrMd    = ReadDrMd(RPort),
  400.             Mask;
  401.  
  402.         Left    = Marker -> LeftEdge + Left * Marker -> TextFontWidth;
  403.         Top    = Marker -> TopEdge + Top * Marker -> TextFontHeight;
  404.  
  405.         if(Kick30)
  406.             Mask = (1L << GetBitMapAttr(RPort -> BitMap,BMA_DEPTH)) - 1;
  407.         else
  408.             Mask = (1L << RPort -> BitMap -> Depth) - 1;
  409.  
  410.         SetPens(RPort,Mask,OldBPen,JAM1 | COMPLEMENT);
  411.  
  412.         FillBox(RPort,Left,Top,Width * Marker -> TextFontWidth,Height * Marker -> TextFontHeight);
  413.  
  414.         SetPens(RPort,OldAPen,OldBPen,OldDrMd);
  415.     }
  416. }
  417.  
  418.     /* WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len,BOOL NeedClipConversion):
  419.      *
  420.      *    Write a string to the clipboard, sans trailing spaces.
  421.      */
  422.  
  423. VOID
  424. WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len,BOOL NeedClipConversion)
  425. {
  426.     while(Len > 0 && String[Len - 1] == ' ')
  427.         Len--;
  428.  
  429.     if(Len)
  430.     {
  431.         if(NeedClipConversion)
  432.         {
  433.             UBYTE    Buffer[256];
  434.             LONG    Size,i;
  435.             STRPTR    Dest;
  436.             UBYTE    c;
  437.  
  438.             do
  439.             {
  440.                 Size = MIN(Len,256);
  441.  
  442.                 Len -= Size;
  443.  
  444.                 for(i = 0, Dest = Buffer ; i < Size ; i++)
  445.                 {
  446.                     if(c = ISOConversion[*String++])
  447.                         *Dest++ = c;
  448.                     else
  449.                         *Dest++ = ' ';
  450.                 }
  451.  
  452.                 if(Dest > Buffer)
  453.                 {
  454.                     Size = (ULONG)Dest - (ULONG)&Buffer[0];
  455.  
  456.                     while(Size > 0 && Buffer[Size - 1] == ' ')
  457.                         Size--;
  458.  
  459.                     if(Size > 0)
  460.                         WriteChunkBytes(Handle,Buffer,Size);
  461.                 }
  462.             }
  463.             while(Len > 0);
  464.         }
  465.         else
  466.             WriteChunkBytes(Handle,String,Len);
  467.     }
  468. }
  469.  
  470.     /* ClipPage(struct BlockMarker *Marker,BOOL Append,BOOL NeedClipConversion):
  471.      *
  472.      *    Send the entire marked page to the clipboard.
  473.      */
  474.  
  475. STATIC VOID
  476. ClipPage(struct BlockMarker *Marker,BOOL Append,BOOL NeedClipConversion)
  477. {
  478.     struct IFFHandle    *Handle;
  479.     APTR             Buffer;
  480.     LONG             Size;
  481.  
  482.     if(Append)
  483.         GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Buffer,&Size);
  484.     else
  485.     {
  486.         Buffer    = NULL;
  487.         Size    = 0;
  488.     }
  489.  
  490.     if(Handle = AllocIFF())
  491.     {
  492.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  493.         {
  494.             InitIFFasClip(Handle);
  495.  
  496.             if(!OpenIFF(Handle,IFFF_WRITE))
  497.             {
  498.                 if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  499.                 {
  500.                     if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  501.                     {
  502.                         LONG    Lines = Marker -> LastLine - Marker -> FirstLine - 1,
  503.                             i;
  504.  
  505.                         if(Buffer)
  506.                         {
  507.                             WriteChunkBytes(Handle,Buffer,Size);
  508.  
  509.                             FreeVecPooled(Buffer);
  510.                         }
  511.  
  512.                         WriteTrimmedString(Handle,&Raster[RasterWidth * Marker -> FirstLine + Marker -> FirstColumn],Marker -> Width - Marker -> FirstColumn,NeedClipConversion);
  513.                         WriteChunkBytes(Handle,"\n",1);
  514.  
  515.                         if(Lines > 0)
  516.                         {
  517.                             STRPTR Line = &Raster[(Marker -> FirstLine + 1) * RasterWidth];
  518.  
  519.                             for(i = 0 ; i < Lines ; i++)
  520.                             {
  521.                                 WriteTrimmedString(Handle,Line,Marker -> Width,NeedClipConversion);
  522.                                 WriteChunkBytes(Handle,"\n",1);
  523.  
  524.                                 Line += RasterWidth;
  525.                             }
  526.                         }
  527.  
  528.                         WriteTrimmedString(Handle,&Raster[RasterWidth * Marker -> LastLine],Marker -> LastColumn,NeedClipConversion);
  529.                         WriteChunkBytes(Handle,"\n",1);
  530.  
  531.                         PopChunk(Handle);
  532.                     }
  533.  
  534.                     PopChunk(Handle);
  535.                 }
  536.  
  537.                 CloseIFF(Handle);
  538.             }
  539.  
  540.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  541.         }
  542.  
  543.         FreeIFF(Handle);
  544.     }
  545. }
  546.  
  547.     /* MarkWord(LONG MouseX,LONG MouseY):
  548.      *
  549.      *    Mark a single word on the main screen (double-click).
  550.      */
  551.  
  552. VOID
  553. MarkWord(LONG MouseX,LONG MouseY)
  554. {
  555.     LONG FirstX,FirstY;
  556.  
  557.     FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  558.     FirstY = MouseY / TextFontHeight;
  559.  
  560.     if(FirstX > LastPrintableColumn)
  561.         FirstX = LastPrintableColumn;
  562.  
  563.     if(FirstY > LastLine)
  564.         FirstY = LastLine;
  565.  
  566.     ObtainSemaphore(RasterSemaphore);
  567.  
  568.     if(Raster[FirstY * RasterWidth + FirstX] != ' ' && Raster[FirstY * RasterWidth + FirstX])
  569.     {
  570.         STRPTR    Line = &Raster[FirstY * RasterWidth];
  571.         LONG    LastX;
  572.  
  573.         LastX = FirstX;
  574.  
  575.         while(FirstX > 0 && Line[FirstX - 1] != ' ')
  576.             FirstX--;
  577.  
  578.         while(LastX < LastPrintableColumn && Line[LastX + 1] != ' ')
  579.             LastX++;
  580.  
  581.         ObtainSemaphore(&TerminalSemaphore);
  582.  
  583.         if(WindowMarker = BM_SetMark(Window -> RPort,ToggleSelect,ToggleSelect,LastPrintableColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,(TextFontWidth * CharCellNominator) / CharCellDenominator,TextFontHeight))
  584.         {
  585.             SetMask(RPort,DepthMask);
  586.  
  587.             Marking = TRUE;
  588.  
  589.             ReportMouse(TRUE,Window);
  590.  
  591.             BM_ExtendMark(WindowMarker,LastX + 1,FirstY,0);
  592.  
  593.             SetClipMenu(TRUE);
  594.         }
  595.  
  596.         ReleaseSemaphore(&TerminalSemaphore);
  597.     }
  598.  
  599.     ReleaseSemaphore(RasterSemaphore);
  600. }
  601.  
  602.     /* SetMarker(LONG MouseX,LONG MouseY):
  603.      *
  604.      *    Anchor a marker to the current mouse position.
  605.      */
  606.  
  607. VOID
  608. SetMarker(LONG MouseX,LONG MouseY)
  609. {
  610.     LONG FirstX,FirstY;
  611.  
  612.     FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  613.     FirstY = MouseY / TextFontHeight;
  614.  
  615.     if(FirstX > LastPrintableColumn)
  616.         FirstX = LastPrintableColumn;
  617.  
  618.     if(FirstY > LastLine)
  619.         FirstY = LastLine;
  620.  
  621.     ObtainSemaphore(&TerminalSemaphore);
  622.  
  623.     if(WindowMarker = BM_SetMark(Window -> RPort,ToggleSelect,ToggleSelect,LastPrintableColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,(TextFontWidth * CharCellNominator) / CharCellDenominator,TextFontHeight))
  624.     {
  625.         SetMask(RPort,DepthMask);
  626.  
  627.         Marking = TRUE;
  628.  
  629.         ReportMouse(TRUE,Window);
  630.  
  631.         SetClipMenu(TRUE);
  632.     }
  633.  
  634.     ReleaseSemaphore(&TerminalSemaphore);
  635. }
  636.  
  637.     /* MoveMarker(LONG MouseX,LONG MouseY):
  638.      *
  639.      *    Move the marker with the mouse.
  640.      */
  641.  
  642. VOID
  643. MoveMarker(LONG MouseX,LONG MouseY)
  644. {
  645.     if(WindowMarker)
  646.     {
  647.         ULONG EffectiveWidth;
  648.  
  649.         ObtainSemaphore(&TerminalSemaphore);
  650.  
  651.         EffectiveWidth = (TextFontWidth * CharCellNominator) / CharCellDenominator;
  652.  
  653.         BM_ExtendMark(WindowMarker,(MouseX + EffectiveWidth - 1) / EffectiveWidth,MouseY / TextFontHeight,0);
  654.  
  655.         ReleaseSemaphore(&TerminalSemaphore);
  656.     }
  657. }
  658.  
  659.     /* DropMarker():
  660.      *
  661.      *    Drop the window marker, restore the window contents.
  662.      */
  663.  
  664. VOID
  665. DropMarker()
  666. {
  667.     if(WindowMarker)
  668.     {
  669.         struct RastPort    *RPort    = WindowMarker -> Object;
  670.         LONG         Mask    = WindowMarker -> WriteMask;
  671.  
  672.         ObtainSemaphore(&TerminalSemaphore);
  673.  
  674.         BM_ClearMark(WindowMarker);
  675.  
  676.         ReleaseSemaphore(&TerminalSemaphore);
  677.  
  678.         SetMask(RPort,Mask);
  679.  
  680.         ReportMouse(FALSE,Window);
  681.  
  682.         WindowMarker = NULL;
  683.  
  684.         Marking = FALSE;
  685.  
  686.         SetClipMenu(FALSE);
  687.     }
  688. }
  689.  
  690.     /* FreeMarker():
  691.      *
  692.      *    Free the main window marker.
  693.      */
  694.  
  695. VOID
  696. FreeMarker()
  697. {
  698.     if(WindowMarker)
  699.     {
  700.         struct RastPort    *RPort    = WindowMarker -> Object;
  701.         LONG         Mask    = WindowMarker -> WriteMask;
  702.  
  703.         FreeVecPooled(WindowMarker);
  704.  
  705.         WindowMarker = NULL;
  706.  
  707.         SetMask(RPort,Mask);
  708.  
  709.         ReportMouse(FALSE,Window);
  710.  
  711.         Marking = FALSE;
  712.  
  713.         SetClipMenu(FALSE);
  714.     }
  715. }
  716.  
  717.     /* ClipMarker(BOOL Append):
  718.      *
  719.      *    Transfer the marked area to the clipboard.
  720.      */
  721.  
  722. VOID
  723. ClipMarker(BOOL Append)
  724. {
  725.     if(WindowMarker)
  726.     {
  727.         ObtainSemaphore(RasterSemaphore);
  728.  
  729.         SetWait(Window);
  730.  
  731.         if(WindowMarker -> FirstColumn == WindowMarker -> Width)
  732.         {
  733.             WindowMarker -> FirstLine++;
  734.  
  735.             WindowMarker -> FirstColumn = 0;
  736.         }
  737.  
  738.         if(WindowMarker -> LastColumn == 0)
  739.         {
  740.             WindowMarker -> LastLine--;
  741.  
  742.             WindowMarker -> LastColumn = WindowMarker -> Width;
  743.         }
  744.  
  745.         if(WindowMarker -> FirstLine <= WindowMarker -> LastLine)
  746.         {
  747.             if(WindowMarker -> FirstLine != WindowMarker -> LastLine || WindowMarker -> FirstColumn != WindowMarker -> LastColumn)
  748.             {
  749.                 if(WindowMarker -> FirstLine == WindowMarker -> LastLine)
  750.                 {
  751.                     if(Config -> TerminalConfig -> FontMode != FONT_STANDARD)
  752.                     {
  753.                         UBYTE    Buffer[256];
  754.                         LONG    Len,i;
  755.                         STRPTR    Dest,
  756.                             Source    = &Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn];
  757.                         LONG    Size    = WindowMarker -> LastColumn - WindowMarker -> FirstColumn;
  758.                         LONG    c;
  759.  
  760.                         if(Append)
  761.                         {
  762.                             do
  763.                             {
  764.                                 Len = MIN(Size,256);
  765.  
  766.                                 Size -= Len;
  767.  
  768.                                 for(i = 0, Dest = Buffer ; i < Len ; i++)
  769.                                 {
  770.                                     if(c = ISOConversion[*Source++])
  771.                                         *Dest++ = c;
  772.                                     else
  773.                                         *Dest++ = ' ';
  774.                                 }
  775.  
  776.                                 if(Dest > Buffer)
  777.                                     AddClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  778.                             }
  779.                             while(Size > 0);
  780.                         }
  781.                         else
  782.                         {
  783.                             BOOL FirstWrite = TRUE;
  784.  
  785.                             do
  786.                             {
  787.                                 Len = MIN(Size,256);
  788.  
  789.                                 Size -= Len;
  790.  
  791.                                 for(i = 0, Dest = Buffer ; i < Len ; i++)
  792.                                 {
  793.                                     if(c = ISOConversion[*Source++])
  794.                                         *Dest++ = c;
  795.                                     else
  796.                                         *Dest++ = ' ';
  797.                                 }
  798.  
  799.                                 if(Dest > Buffer)
  800.                                 {
  801.                                     if(FirstWrite)
  802.                                     {
  803.                                         FirstWrite = FALSE;
  804.  
  805.                                         SaveClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  806.                                     }
  807.                                     else
  808.                                         AddClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  809.                                 }
  810.                             }
  811.                             while(Size > 0);
  812.                         }
  813.                     }
  814.                     else
  815.                     {
  816.                         if(Append)
  817.                             AddClip(&Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn],WindowMarker -> LastColumn - WindowMarker -> FirstColumn);
  818.                         else
  819.                             SaveClip(&Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn],WindowMarker -> LastColumn - WindowMarker -> FirstColumn);
  820.                     }
  821.                 }
  822.                 else
  823.                     ClipPage(WindowMarker,Append,Config -> TerminalConfig -> FontMode != FONT_STANDARD);
  824.             }
  825.         }
  826.  
  827.         ClrWait(Window);
  828.  
  829.         ReleaseSemaphore(RasterSemaphore);
  830.  
  831.         DropMarker();
  832.     }
  833. }
  834.